﻿using albert.DB.SqlServer;
using albert.Model;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace MyReflection20180618
{
    class Program
    {
        /// <summary>
        /// 1 dll-IL-metadata-反射
        /// 2. 反射加载dll，读取module,类，方法，特性
        /// 3. 反射创建对象，反射+简单工厂+配置文件 选修：破坏单例 创建泛型
        /// 4. 反射调用实例方法 静态方法 重载方法  选修：调用私有方法 调用泛型方法
        /// 5. 反射字段和属性，分别获取值和设置值
        /// 6. 反射的好处和局限
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            try
            {
                {
                    Assembly assembly = Assembly.Load("albert.DB.SqlServer");
                    Type typeHelper = assembly.GetType("albert.DB.SqlServer.Singleton");
                    object oDBHelper = Activator.CreateInstance(typeHelper, true);

                }

                #region 反射调用实例方法 静态方法 重载方法  选修：调用私有方法 调用泛型方法
                {
                    //MVC
                    Console.WriteLine("**************************************************");
                    Assembly assembly = Assembly.Load("albert.DB.SqlServer");
                    Type typeTest = assembly.GetType("albert.DB.SqlServer.ReflectionTest");

                    object oTest = Activator.CreateInstance(typeTest);
                    object oTest1 = Activator.CreateInstance(typeTest, new object[] { "albert" });
                    object oTest2 = Activator.CreateInstance(typeTest, new object[] { 110 });

                    {
                        MethodInfo method = typeTest.GetMethod("Show1");
                        method.Invoke(oTest, null);
                    }

                    {
                        MethodInfo method = typeTest.GetMethod("Show2");
                        method.Invoke(oTest, new object[] { 110 });
                    }

                    {
                        //static method
                        MethodInfo method = typeTest.GetMethod("Show5");
                        method.Invoke(oTest, new object[] { "albert" });
                        method.Invoke(null, new object[] { "albert1" });
                    }

                    {
                        MethodInfo method = typeTest.GetMethod("Show3",new Type[] { typeof(int)});
                        method.Invoke(oTest, new object[] { 110 });
                    }

                    {
                        MethodInfo method = typeTest.GetMethod("Show3", new Type[] { typeof(string) });
                        method.Invoke(oTest, new object[] { "albert" });
                    }

                    {
                        MethodInfo method = typeTest.GetMethod("Show3", new Type[] { typeof(int), typeof(string) });
                        method.Invoke(oTest, new object[] { 110,"albert" });
                    }

                    {
                        MethodInfo method = typeTest.GetMethod("Show3", new Type[] { typeof(string), typeof(int) });
                        method.Invoke(oTest, new object[] { "string",110 });
                    }

                    {
                        MethodInfo method = typeTest.GetMethod("Show4", BindingFlags.Instance|BindingFlags.NonPublic);
                        method.Invoke(oTest, new object[] { "albert" });
                    }

                }
                #endregion

                #region 反射字段和属性，分别获取值和设置值
                {
                    //可用于 ORM 框架
                    Console.WriteLine("**************************************************");
                    People people = new People();
                    people.Id = 100;
                    people.Name = "albert";

                    Console.WriteLine("Id={0} name={1}",people.Id,people.Name);
                }

                {
                    Type type = typeof(People);
                    object oPeople = Activator.CreateInstance(type);

                    //property
                    foreach(var item in type.GetProperties())
                    {
                        Console.WriteLine("{0} {1}",item.Name,item.GetValue(oPeople));

                        if (item.Name.Equals("Id"))
                            item.SetValue(oPeople,101);
                        else if(item.Name.Equals("Name"))
                            item.SetValue(oPeople, "aaa");

                        Console.WriteLine("{0} {1}", item.Name, item.GetValue(oPeople));
                    }
                    //field
                    foreach (var item in type.GetFields())
                    {
                        Console.WriteLine("{0} {1}", item.Name, item.GetValue(oPeople));
                        item.SetValue(oPeople, "description");
                        Console.WriteLine("{0} {1}", item.Name, item.GetValue(oPeople));
                    }

                    //ORM
                    {
                        SqlServerHelper dbHelper = new SqlServerHelper();
                        dbHelper.Get<User>(1);
                    }

                }
                #endregion

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }
}
